package com.bbcare.followup.plat.controller;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;


import com.bbcare.comm.*;
import com.bbcare.followup.plat.service.HisIdMapperService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bbcare.department.plat.service.IBsStaticParamService;
import com.bbcare.followup.plat.entity.Patient;
import com.bbcare.followup.plat.entity.PatientInfoHis;
import com.bbcare.followup.plat.service.IPatientInfoHisService;
import com.bbcare.followup.plat.service.IPatientService;

/**
 *
 * @author tao
 *
 */
@Controller
@RequestMapping("/service/patient")
public class PatientInfoHisController {
    private final Log logger = LogFactory.getLog(PatientInfoHisController.class);

    @Autowired
    private IPatientInfoHisService patientInfoHisService;

    @Autowired
    private IPatientService patientSerivce;

    @Autowired
    private IBsStaticParamService bsStaticParamService;

    @Autowired
    private HisIdMapperService mapperService;

    // 根据条件查询患者登记历史信息
    @ResponseBody
    @RequestMapping("/history/detail")
    public ResultModel<Object> getPatientHisInfo(@RequestBody String jsonStr) throws Exception {
        logger.warn("in getPatientHisInfo----arg==" + jsonStr);
        JSONObject jsonEsb = JSON.parseObject(jsonStr);
        JSONObject requestParam = jsonEsb.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD); // 统一节点处理
        if (null == requestParam) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！");
        }
        String id = requestParam.getString("id");
        if (StringUtils.isBlank(id)) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "参数校验失败，ID不能为空");
        }
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("id", id);
        List<PatientInfoHis> patientInfoHis = patientInfoHisService.getPatientInfoHis(paramMap);
        if (!CollectionUtils.isEmpty(patientInfoHis)) {
            return new ResultModel<Object>(patientInfoHis.get(0));
        }
        return new ResultModel<Object>(null);
    }

    // 患者登记历史信息修改保存
    @ResponseBody
    @RequestMapping("/history/modify")
    public ResultModel<Object> patientHisInfoModify(@RequestBody String arg, HttpServletRequest request)
            throws Exception {
        logger.info("in getFollowQueueList----arg==" + arg);
        JSONObject jsonEsb = JSON.parseObject(arg);
        JSONObject requestParam = jsonEsb.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD); // 统一节点处理
        if (null == requestParam) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！");
        }

        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String authorName = (String) sessionMap.get("authorName");// 登录账号医生姓名
        String tenantId = (String) sessionMap.get("tenantId");// 租户id

        Map<String, Object> paramMap = new HashMap<String, Object>();
        String userId = requestParam.getString("userId");
        String name = requestParam.getString("name");
        String detail = requestParam.getString("detail");
        String relationShip = requestParam.getString("relationShip");
        String id = requestParam.getString("id");
        String type = requestParam.getString("type");
        if ((StringUtils.isBlank(name) && StringUtils.isBlank(detail)) || StringUtils.isBlank(type)) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "参数校验失败，名称和详情不能为空");

        }
        if (!type.equals(Constants.PATIENT_ACTIVE_BUSI_TYPE_1) && !type.equals(Constants.PATIENT_ACTIVE_BUSI_TYPE_2)
                && !type.equals(Constants.PATIENT_ACTIVE_BUSI_TYPE_3)
                && !type.equals(Constants.PATIENT_ACTIVE_BUSI_TYPE_4)) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "参数校验失败，传入未知的类型");
        }
        paramMap.put("authorId", authorId);
        paramMap.put("name", name);
        paramMap.put("detail", detail);
        paramMap.put("relationShip", relationShip);
        paramMap.put("id", id);
        paramMap.put("type", type);
        paramMap.put("userId", userId);
        paramMap.put("tenantId", tenantId);

        // 记录操作记录使用
        paramMap.put("authorName", authorName);
        Patient patient = patientSerivce.getPatient(paramMap);
        if (null == patient) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_NOT_EXIST, "患者信息不存在");
        }
        paramMap.put("userName", patient.getUserName());
        patientInfoHisService.patientInfoHisModify(paramMap);
        logger.info("out patientHisInfoModify----arg==");
        return new ResultModel<Object>(null);
    }

    // 删除登记历史
    @ResponseBody
    @RequestMapping("/history/remove")
    public ResultModel<Object> deleteHisInfo(@RequestBody String jsonStr, HttpServletRequest request) throws Exception {
        logger.info("in deleteContact----arg==" + jsonStr);
        JSONObject jsonEsb = JSON.parseObject(jsonStr);
        JSONObject requestParam = jsonEsb.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD); // 统一节点处理
        if (null == requestParam) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！");
        }
        String id = requestParam.getString("id");

        if (StringUtils.isEmpty(id)) {
            // 返回空 或者返回校验失败
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "参数校验失败，要删除的病史ID不能为空");
        }
        // List<String> list = JSON.parseArray(ids, String.class);
        /*
         * if(CollectionUtils.isEmpty(list)){
         * logger.debug("out deleteContact----arg== null"); return new
         * ResultModel<DepartmentBasic>(null); }
         */

        patientInfoHisService.patientInfoHisDelete(requestParam);
        logger.info("out deleteHisInfo----arg==");
        return new ResultModel<Object>(null);
    }

    /**
     *
     * 患者活跃信息查询
     *
     * @param arg
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/activeInfo/list")
    public QueryModel<Map<String, Object>> getActiveInfoList(HttpServletRequest request, @RequestBody String arg)
            throws Exception {
        logger.warn("in getActiveInfoList----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            // 后续重写异常类
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "非json格式");
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            logger.warn("in savePatientInfo----no data node...");
            // 前台必须传data节点，否则报错返回（后续重写异常类）
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！");
        }

        /*
         * String queueId = jsonData.getString("queueId");
         * if(StringUtils.isBlank(queueId)){ throw new AppException(ErrorCode.
         * FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
         * "参数格式不正确,queueId不能为空"); }
         */

        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id

        Map<String, Object> paramMap = jsonData;
        List<String> busiCategorys = new ArrayList<String>();
        List<String> testbusiCategorys = new ArrayList<String>();
        if (null != paramMap.get("busiCategory") && !"".equals(paramMap.get("busiCategory"))) {
            if (Constants.PATIENT_ACTIVE_BUSI_TYPE_6.equals((String) paramMap.get("busiCategory"))) {
                // 监测数据 用户自己上传部分 无队列或租户信息
                testbusiCategorys.add((String) paramMap.get("busiCategory"));
                paramMap.put("testbusiCategorys", busiCategorys);
            }
            busiCategorys.add((String) paramMap.get("busiCategory"));
            paramMap.put("busiCategorys", busiCategorys);
        } else {
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_1);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_2);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_3);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_4);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_5);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_6);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_7);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_8);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_9);
            busiCategorys.add(Constants.PATIENT_ACTIVE_APP_LOGIN);
            paramMap.put("busiCategorys", busiCategorys);

            // 患者自己上传监测数据 没有保存队列和租户 需分条件开查询
            testbusiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_6);
            paramMap.put("testbusiCategorys", busiCategorys);
        }

        paramMap.put("authorId", authorId);
        paramMap.put("tenantId", tenantId);
        List<Map<String, Object>> activeInfoList = patientInfoHisService.getActiveInfoList(paramMap);
        int total = 0;
        if (!CollectionUtils.isEmpty(activeInfoList)) {
            total = patientInfoHisService.getActiveInfoCount(paramMap);
        }
        Map<String, Object> paramTemp = new HashMap<String, Object>();
        paramTemp.put("deptId", tenantId);
        paramTemp.put("type", Constants.QUEUE_BUSI_TYPE_CODE);
        Map<String, String> busiMap = bsStaticParamService.getStaticParamsForMap(paramTemp);

        if (!CollectionUtils.isEmpty(activeInfoList)) {
            for (int i = 0; i < activeInfoList.size(); i++) {
                // 业务类型转换
                activeInfoList.get(i).put("busiTypeName", busiMap.get(activeInfoList.get(i).get("busiCategory")));
            }
        }
        logger.info(JSONObject.toJSONString(activeInfoList));
        return new QueryModel<Map<String, Object>>(activeInfoList, total);
    }

    /**
     * 患者相关操作医生查询 -按队列、患者纬度查询
     *
     * @param request
     * @param arg
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/activeInfo/doctorList")
    public ResultModel<Object> getActiveDoctorsByUserAndQueue(HttpServletRequest request, @RequestBody String arg)
            throws Exception {
        logger.warn("in getActiveDoctorsByUserAndQueue----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            // 后续重写异常类
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "非json格式");
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            logger.warn("in savePatientInfo----no data node...");
            // 前台必须传data节点，否则报错返回（后续重写异常类）
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！");
        }

        String queueId = jsonData.getString("queueId");
        String userId = jsonData.getString("userId");
        if (StringUtils.isBlank(queueId)) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "参数校验失败,队列ID不能为空");
        }
        if (StringUtils.isBlank(userId)) {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "参数校验失败,患者ID不能为空");
        }

        List<String> busiCategorys = new ArrayList<String>();
        if (null != jsonData.get("busiCategory") && !"".equals(jsonData.get("busiCategory"))) {
            if ("0".equals((String) jsonData.get("busiCategory"))) {// 当传入类型为其他
                                                                    // 先不处理
                // busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_7);
                // busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_8);
                // busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_9);
                // busiCategorys.add(Constants.DOCTOR_ACTIVE_BUSI_TYPE_10);
            } else {
                busiCategorys.add((String) jsonData.get("busiCategory"));
            }
            jsonData.put("busiCategorys", busiCategorys);
        } else {
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_1);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_2);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_3);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_4);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_5);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_6);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_7);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_8);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_9);
            busiCategorys.add(Constants.PATIENT_ACTIVE_APP_LOGIN);
            jsonData.put("busiCategorys", busiCategorys);
        }

        List<Map<String, Object>> doctorList = patientInfoHisService.getActiveDoctorsByUserAndQueue(jsonData);
        logger.warn("out getActiveDoctorsByUserAndQueue----arg==" + arg);
        return new ResultModel<Object>(doctorList);
    }

    /**
     * 活跃度患者按日月统计
     *
     * @param request
     * @param arg
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/activeInfo/trendStatistics")
    public ResultModel<Object> getActivePatientTrendStatistics(HttpServletRequest request, @RequestBody String arg)
            throws Exception {
        logger.warn("in getActivePatientTrendStatistics----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            // 后续重写异常类
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "非json格式");
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回（后续重写异常类）
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！");
        }

        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id

        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.putAll(jsonData);
        paramMap.put("authorId", authorId);
        paramMap.put("tenantId", tenantId);

        List<String> busiCategorys = new ArrayList<String>();
        List<String> testbusiCategorys = new ArrayList<String>();
        if (null != paramMap.get("busiCategory") && !"".equals(paramMap.get("busiCategory"))) {
            if (Constants.PATIENT_ACTIVE_BUSI_TYPE_6.equals((String) paramMap.get("busiCategory"))) {
                // 监测数据 用户自己上传部分 无队列或租户信息
                testbusiCategorys.add((String) paramMap.get("busiCategory"));
                paramMap.put("testbusiCategorys", busiCategorys);
            }
            busiCategorys.add((String) paramMap.get("busiCategory"));
            paramMap.put("busiCategorys", busiCategorys);
        } else {
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_1);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_2);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_3);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_4);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_5);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_6);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_7);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_8);
            busiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_9);
            busiCategorys.add(Constants.PATIENT_ACTIVE_APP_LOGIN);
            paramMap.put("busiCategorys", busiCategorys);

            // 患者自己上传监测数据 没有保存队列和租户 需分条件开查询
            testbusiCategorys.add(Constants.PATIENT_ACTIVE_BUSI_TYPE_6);
            paramMap.put("testbusiCategorys", busiCategorys);
        }

        List<Map<String, Object>> list = patientInfoHisService.getActivePatientTrendStatistics(paramMap);
        logger.warn("out getActivePatientTrendStatistics----arg==" + arg);
        return new ResultModel<Object>(list);
    }

    /**
     * 失访患者list查询
     *
     * @param
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/lost/patientLostListQuery")
    public Map<String, Object> listPatientLost(HttpServletRequest request, @RequestBody String arg) throws Exception {
        logger.warn("in listPatientLost----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        HashMap<String, Object> paramMap = new HashMap<String, Object>();
        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id

        paramMap.put("authorId", authorId);
        paramMap.put("tenantId", tenantId);

        String phoneNo = jsonData.getString("phoneNum");
        String userName = jsonData.getString("patientName");// 可以是姓氏或姓名
        int page = jsonData.getIntValue("page");
        int rows = jsonData.getIntValue("rows");
        page = page == 0 ? 1 : page;
        rows = rows == 0 ? 20 : rows;

        if (null != phoneNo && !"".equals(phoneNo)) {
            paramMap.put("phoneNo", phoneNo);
        }
        if (null != userName && !"".equals(userName)) {
            paramMap.put("userName", userName);
        }
        paramMap.put("start", (page - 1) * rows);
        paramMap.put("end", rows);

        // 增加队列id和患者来源
        paramMap.put("queueId", jsonData.getString("queueId"));
        paramMap.put("qryEndTime", jsonData.getString("qryEndTime"));
        paramMap.put("qryStartTime", jsonData.getString("qryStartTime"));
        if (!StringUtils.isEmpty(jsonData.getString("hisNo"))) {
            paramMap.put("hisNo", jsonData.getString("hisNo"));
        }

        Integer ageTo = jsonData.getInteger("ageTo");
        Integer ageFrom = jsonData.getInteger("ageFrom");

        Calendar to = Calendar.getInstance();
        if (ageTo != null) {
            to.add(Calendar.MONTH, -ageTo);
            paramMap.put("ageTo", DateUtil.getDate_8(to.getTime()));
        }

        Calendar from = Calendar.getInstance();
        if (ageFrom != null) {
            from.add(Calendar.MONTH, -ageFrom);
            paramMap.put("ageFrom", DateUtil.getDate_8(from.getTime()));
        }

        // 针对Datatable特殊处理
        String jsonStr = jsonData.getString(Constants.INF_INPUTPARAM_DATATABLE_FIELD);
        int draw = 0;
        if (!StringUtils.isEmpty(jsonStr)) {
            JSONObject jsonTable = (JSONObject) JSONObject.parse(jsonStr);
            draw = jsonTable.getIntValue("draw");
            paramMap.put("start", jsonTable.getIntValue("start"));
            paramMap.put("end", jsonTable.getIntValue("length"));
        }

        Map<String, Object> retMap = patientInfoHisService.listPatientLost(paramMap);
        // 针对Datatable特殊处理
        if (!StringUtils.isEmpty(jsonStr)) {
            retMap.put("draw", draw);
            retMap.put("recordsTotal", retMap.get("total"));
            retMap.put("recordsFiltered", retMap.get("total"));
        }
        retMap.put("success", true);

        return retMap;
    }

    /**
     * 失访原因list查询
     *
     * @param
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/lost/followLostReasonQuery")
    public ResultModel<Object> listFollowLostReason(HttpServletRequest request, @RequestBody String arg)
            throws Exception {
        logger.warn("in listFollowLostReason----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            // 后续重写异常类
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "非json格式");
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回（后续重写异常类）
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！");
        }

        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id

        Map<String, Object> map = new HashMap<String, Object>();
        map.putAll(jsonData);
        map.put("authorId", authorId);
        map.put("tenantId", tenantId);

        Map<String, Object> mapOut = patientInfoHisService.listLostReason(map);
        return new ResultModel<Object>(mapOut);
    }

    /**
     * 失访患者失访原因登记或修改
     *
     * @param
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/lost/patientLostInfoModify")
    public ResultModel<Object> updatePtLostInfo(HttpServletRequest request, @RequestBody String arg) throws Exception {
        logger.warn("in updatePtLostInfo----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            // 后续重写异常类
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "非json格式");
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回（后续重写异常类）
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！");
        }

        JSONObject jsonOpInfo = jsonData.getJSONObject("oprInfo");
        if (null == jsonOpInfo) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无oprInfo节点！"));
        }
        String opCode = jsonOpInfo.getString("opCode");
        if (null == opCode || "".equals(opCode)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无操作编码节点！"));
        }
        String opNote = jsonOpInfo.getString("opNote");
        if (null == opNote || "".equals(opNote)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作备注未传！"));
        }
        String opType = jsonOpInfo.getString("opType");
        if (null == opType || "".equals(opType)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作类型未传！"));
        }

        JSONObject jsonLost = jsonData.getJSONObject("lostInfo");
        if (null == jsonLost) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无lostInfo节点！"));
        }
        String ptLostId = jsonLost.getString("ptLostId");
        if (null == ptLostId || "".equals(ptLostId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                    "入参节点错误，未传入患者失访实例id或值为空！"));
        }
        String reasonId = jsonLost.getString("reasonId");
        if (null == reasonId || "".equals(reasonId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，失访原因id未传或值为空！"));
        }
        String userId = jsonLost.getString("patientId");
        if (null == userId || "".equals(userId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，患者id未传或值为空！"));
        }
        String queueId = jsonLost.getString("followQueueId");
        if (null == queueId || "".equals(queueId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无队列id节点！"));
        }

        String updateTime = DateUtil.getTimeString(DateUtil.getSysDateA());// 当前时间
        String updateAccept = SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID);// 操作流水

        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id
        String authorName = (String) sessionMap.get("authorName");// 登录账号医生姓名

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("updateTime", updateTime);
        map.put("updateAccept", updateAccept);

        map.put("userId", userId);
        map.put("queueId", queueId);
        map.put("ptLostId", ptLostId);
        map.put("reasonId", reasonId);
        map.put("opCode", opCode);
        map.put("opNote", opNote);
        map.put("opType", opType);

        map.put("authorId", authorId);
        map.put("tenantId", tenantId);
        map.put("authorName", authorName);

        Map<String, Object> mapOut = new HashMap<String, Object>();
        patientInfoHisService.updatePtLostInfo(map);

        return new ResultModel<Object>(mapOut);
    }

    // 患者随访提醒记录查询
    @ResponseBody
    @RequestMapping("/inform/ptInformRdQuery")
    public Map<String, Object> listPtInformRd(@RequestBody String arg, HttpServletRequest request) throws Exception {
        logger.warn("in listPtInformRd----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        HashMap<String, Object> paramMap = new HashMap<String, Object>();
        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id

        paramMap.put("authorId", authorId);
        paramMap.put("tenantId", tenantId);

        String sendStatus = jsonData.getString("sendStatus");
        String informType = jsonData.getString("informType");
        String phoneNo = jsonData.getString("phoneNum");
        String userName = jsonData.getString("patientName");// 可以是姓氏或姓名
        int page = jsonData.getIntValue("page");
        int rows = jsonData.getIntValue("rows");
        page = page == 0 ? 1 : page;
        rows = rows == 0 ? 20 : rows;

        if (null != phoneNo && !"".equals(phoneNo)) {
            paramMap.put("phoneNo", phoneNo);
        }
        if (null != userName && !"".equals(userName)) {
            paramMap.put("userName", userName);
        }
        if (!StringUtils.isEmpty(informType)) {
            paramMap.put("informType", informType);
        }
        if (!StringUtils.isEmpty(sendStatus)) {
            paramMap.put("sendStatus", sendStatus);
        }
        paramMap.put("start", (page - 1) * rows);
        paramMap.put("end", rows);

        // 增加队列id和患者来源
        paramMap.put("queueId", jsonData.getString("queueId"));
        paramMap.put("qryEndTime", jsonData.getString("qryEndTime"));
        paramMap.put("qryStartTime", jsonData.getString("qryStartTime"));
        if (!StringUtils.isEmpty(jsonData.getString("hisNo"))) {
            paramMap.put("hisNo", jsonData.getString("hisNo"));
        }

        // 针对Datatable特殊处理
        String jsonStr = jsonData.getString(Constants.INF_INPUTPARAM_DATATABLE_FIELD);
        int draw = 0;
        if (!StringUtils.isEmpty(jsonStr)) {
            JSONObject jsonTable = (JSONObject) JSONObject.parse(jsonStr);
            draw = jsonTable.getIntValue("draw");
            paramMap.put("start", jsonTable.getIntValue("start"));
            paramMap.put("end", jsonTable.getIntValue("length"));
        }

        HashMap<String, Object> retMap = patientInfoHisService.listPtInformRd(paramMap);
        // 针对Datatable特殊处理
        if (!StringUtils.isEmpty(jsonStr)) {
            retMap.put("draw", draw);
            retMap.put("recordsTotal", retMap.get("total"));
            retMap.put("recordsFiltered", retMap.get("total"));
        }
        retMap.put("success", true);

        return retMap;
    }

    // 医生在门诊时对患者进行随访提醒
    @ResponseBody
    @RequestMapping("/inform/ptWarnInformDeal")
    public Object sendPtWarnInform(@RequestBody String arg, HttpServletRequest request) throws Exception {
        logger.warn("in sendPtWarnInform----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        JSONObject jsonOpInfo = jsonData.getJSONObject("oprInfo");
        if (null == jsonOpInfo) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无oprInfo节点！"));
        }
        String opCode = jsonOpInfo.getString("opCode");
        if (StringUtils.isEmpty(opCode)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无操作编码节点！"));
        }
        String opNote = jsonOpInfo.getString("opNote");
        if (StringUtils.isEmpty(opNote)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作备注未传！"));
        }
        String opType = jsonOpInfo.getString("opType");
        if (StringUtils.isEmpty(opType)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作类型未传！"));
        }

        JSONObject informInfo = jsonData.getJSONObject("informInfo");
        if (null == informInfo) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                    "入参节点错误，无informInfo节点！"));
        }
        String ptSchemeId = informInfo.getString("ptSchemeId");
        if (StringUtils.isEmpty(ptSchemeId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                    "入参节点错误，未传入患者队列实例id或值为空！"));
        }
        String taskId = informInfo.getString("taskId");
        if (StringUtils.isEmpty(taskId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，队列id未传或值为空！"));
        }
        String userId = informInfo.getString("patientId");
        if (StringUtils.isEmpty(userId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，患者id未传或值为空！"));
        }
        String queueId = informInfo.getString("followQueueId");
        if (StringUtils.isEmpty(queueId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无队列id节点或值为空！"));
        }
        String taskName = informInfo.getString("taskName");
        if (StringUtils.isEmpty(taskName)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无队列名称节点或值为空！"));
        }

        String informType = informInfo.getString("informType");
        if (StringUtils.isEmpty(informType)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无提醒类型节点或值为空！"));
        }

       /* String orderAddress = informInfo.getString("orderAddress");
        if (StringUtils.isEmpty(orderAddress)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无门诊地址节点或值为空！"));
        }
        String orderDate = informInfo.getString("orderDate");
        if (StringUtils.isEmpty(orderDate)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无门诊时间节点或值为空！"));
        }*/

        // 发送主机ip
        String ipAddress = "";
        try {
            InetAddress netAddress = InetAddress.getLocalHost();
            ipAddress = netAddress.getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            ipAddress = "";
        }

        String updateTime = DateUtil.getTimeString(DateUtil.getSysDateA());// 当前时间
        String updateAccept = SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID);// 操作流水

        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id
        String authorName = (String) sessionMap.get("authorName");// 登录账号医生姓名

        Map<String, Object> map = new HashMap<String, Object>();
        /*map.put("orderAddress", orderAddress);
        map.put("orderDate", orderDate);*/
        map.put("informType", informType);

        map.put("updateTime", updateTime);
        map.put("updateAccept", updateAccept);

        map.put("userId", userId);
        map.put("queueId", queueId);
        map.put("taskName", taskName);
        map.put("ptSchemeId", ptSchemeId);
        map.put("taskId", taskId);
        map.put("opCode", opCode);
        map.put("opNote", opNote);
        map.put("opType", opType);
        map.put("ipAddress", ipAddress);

        map.put("authorId", authorId);
        map.put("tenantId", tenantId);
        map.put("authorName", authorName);
//        patientInfoHisService.dealPatientWinTaskSmsSend(map);
        patientInfoHisService.dealPatientWinTaskSmsSendByDoctor(map);
        Map<String, Object> mapOut = new HashMap<String, Object>();
        return new ResultModel<Object>(mapOut);
    }

    // 临期（警戒期）患者信息List查询
    @ResponseBody
    @RequestMapping("/ptWarnQueueListQuery")
    public Object listPtWarnQueue(@RequestBody String arg, HttpServletRequest request) throws Exception {
        logger.warn("in listPtWarnQueue----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        HashMap<String, Object> paramMap = new HashMap<String, Object>();
        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id

        paramMap.put("authorId", authorId);
        paramMap.put("tenantId", tenantId);

        String phoneNo = jsonData.getString("phoneNum");
        String userName = jsonData.getString("patientName");// 可以是姓氏或姓名
        int page = jsonData.getIntValue("page");
        int rows = jsonData.getIntValue("rows");
        page = page == 0 ? Constants.APP_PAGE_FOR_INIT : page;
        rows = rows == 0 ? Constants.APP_ROWS_FOR_INIT : rows;

        if (null != phoneNo && !"".equals(phoneNo)) {
            paramMap.put("phoneNo", phoneNo);
        }
        if (null != userName && !"".equals(userName)) {
            paramMap.put("userName", userName);
        }
        paramMap.put("start", (page - 1) * rows);
        paramMap.put("end", rows);

        // 增加队列id和患者来源
        if (!StringUtils.isEmpty(jsonData.getString("queueId"))) {
            paramMap.put("queueId", jsonData.getString("queueId"));
        }
        if (!StringUtils.isEmpty(jsonData.getString("opType"))) {
            paramMap.put("sourceType", jsonData.getString("opType"));
        }
        if (!StringUtils.isEmpty(jsonData.getString("qryEndTime"))) {
            paramMap.put("qryEndTime", jsonData.getString("qryEndTime"));
        }
        if (!StringUtils.isEmpty(jsonData.getString("qryStartTime"))) {
            paramMap.put("qryStartTime", jsonData.getString("qryStartTime"));
        }
        if (!StringUtils.isEmpty(jsonData.getString("hisNo"))) {
            paramMap.put("hisNo", jsonData.getString("hisNo"));
        }

        Integer ageTo = jsonData.getInteger("ageTo");
        Integer ageFrom = jsonData.getInteger("ageFrom");

        Calendar to = Calendar.getInstance();
        if (ageTo != null) {
            to.add(Calendar.MONTH, -ageTo);
            paramMap.put("ageTo", DateUtil.getDate_8(to.getTime()));
        }

        Calendar from = Calendar.getInstance();
        if (ageFrom != null) {
            from.add(Calendar.MONTH, -ageFrom);
            paramMap.put("ageFrom", DateUtil.getDate_8(from.getTime()));
        }

        // 针对Datatable特殊处理
        String jsonStr = jsonData.getString(Constants.INF_INPUTPARAM_DATATABLE_FIELD);
        int draw = 0;
        if (!StringUtils.isEmpty(jsonStr)) {
            JSONObject jsonTable = (JSONObject) JSONObject.parse(jsonStr);
            draw = jsonTable.getIntValue("draw");
            paramMap.put("start", jsonTable.getIntValue("start"));
            paramMap.put("end", jsonTable.getIntValue("length"));
        }
        HashMap<String, Object> retMap = patientInfoHisService.listPtWarnQueue(paramMap);
        // 针对Datatable特殊处理
        if (!StringUtils.isEmpty(jsonStr)) {
            retMap.put("draw", draw);
            retMap.put("recordsTotal", retMap.get("total"));
            retMap.put("recordsFiltered", retMap.get("total"));
        }

        return retMap;
    }

    // 患者随访提醒门诊地址及排班计划查询
    @ResponseBody
    @RequestMapping("/inform/ptInformScheduleQuery")
    public Object getPtInformSchedule(@RequestBody String arg, HttpServletRequest request) throws Exception {
        logger.warn("in getPtInformSchedule----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        HashMap<String, Object> paramMap = new HashMap<String, Object>();
        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id
        String deptId = (String) sessionMap.get("deptId");// 科室id

        paramMap.put("authorId", authorId);
        paramMap.put("tenantId", tenantId);
        paramMap.put("deptId", deptId);

        String queueId = jsonData.getString("followQueueId");
        String patientId = jsonData.getString("patientId");
        String taskId = jsonData.getString("taskId");

        if (StringUtils.isEmpty(patientId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无患者id节点或值为空！"));
        }
        if (StringUtils.isEmpty(taskId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                    "入参节点错误，无任务实例id节点或值为空！"));
        }
        if (StringUtils.isEmpty(queueId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无队列id节点或值为空！"));
        }

        // 增加队列id和患者来源
        paramMap.put("queueId", queueId);
        paramMap.put("patientId", patientId);
        paramMap.put("taskId", taskId);

        Map<String, Object> retMap = patientInfoHisService.getPtScheduleInfo(paramMap);

        return new ResultModel<Object>(retMap);
    }

    // 从队列中删除某个患者
    @ResponseBody
    @RequestMapping("/history/patientDel")
    public Object removePatientFromQueue(@RequestBody String arg, HttpServletRequest request) throws Exception {
        logger.warn("in removePatientFromQueue----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参格式错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        JSONObject jsonOpInfo = jsonData.getJSONObject("oprInfo");
        if (null == jsonOpInfo) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无oprInfo节点！"));
        }
        String opCode = jsonOpInfo.getString("opCode");
        if (StringUtils.isEmpty(opCode)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无操作编码节点！"));
        }
        String opNote = jsonOpInfo.getString("opNote");
        if (StringUtils.isEmpty(opNote)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作备注未传！"));
        }
        String opType = jsonOpInfo.getString("opType");
        if (StringUtils.isEmpty(opType)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作类型未传！"));
        }

        JSONObject patientInfo = jsonData.getJSONObject("patientInfo");
        if (null == patientInfo) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                    "入参节点错误，无patientInfo节点！"));
        }
        String ptSchemeId = patientInfo.getString("ptSchemeId");
        if (StringUtils.isEmpty(ptSchemeId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                    "入参节点错误，未传入患者队列实例id或值为空！"));
        }
        String userId = patientInfo.getString("patientId");
        if (StringUtils.isEmpty(userId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，患者id未传或值为空！"));
        }
        String queueId = patientInfo.getString("followQueueId");
        if (StringUtils.isEmpty(queueId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无队列id节点或值为空！"));
        }

        String updateTime = DateUtil.getTimeString(DateUtil.getSysDateA());// 当前时间
        String updateAccept = SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID);// 操作流水

        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        String authorId = (String) sessionMap.get("authorId");
        String tenantId = (String) sessionMap.get("tenantId");// 租户id
        String authorName = (String) sessionMap.get("authorName");// 登录账号医生姓名

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("updateTime", updateTime);
        map.put("updateAccept", updateAccept);
        map.put("userId", userId);
        map.put("queueId", queueId);
        map.put("ptSchemeId", ptSchemeId);
        map.put("opCode", opCode);
        map.put("opNote", opNote);
        map.put("opType", opType);
        map.put("authorId", authorId);
        map.put("tenantId", tenantId);
        map.put("authorName", authorName);
        Map<String, Object> mapOut = patientInfoHisService.removePtInfoFromQueue(map);

        // type=10 删除患者
        int type = 10;
        // system=1 2.0系统
        int system = 1;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type",type);
        jsonObject.put("userId",userId);
        jsonObject.put("queueId",queueId);
        jsonObject.put("system",system);
        String sendMsg = jsonObject.toJSONString();
        if (StringUtils.isNotBlank(PropertiesUtils.getProperty("redirectUrl"))) {
            //如果config.properties中有redirectUrl配置项，才会发送请求。没有配置项，就不发送了。
            HttpUtil.postData(PropertiesUtils.getProperty("redirectUrl"), sendMsg);
        }

        return new ResultModel<Object>(mapOut);
    }

    // 给患者添加临时任务（当前日期无可编辑任务）
    @ResponseBody
    @RequestMapping("/addTempTask")
    public ResultModel<Object> saveNewTempPatientTask(@RequestBody String arg, HttpServletRequest request) throws Exception {
        logger.warn("in saveNewTempPatientTask----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            ex.printStackTrace();
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }
        JSONObject jsonTask = jsonData.getJSONObject("taskInfo");
        if (null == jsonTask) {
            // 前台必须传task节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无task节点！"));
        }
        String queueId = jsonTask.getString("followQueueId");
        if (null == queueId || "".equals(queueId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无队列id节点！"));
        }
        String ptSchemeId = jsonTask.getString("ptSchemeId");
        if (null == ptSchemeId || "".equals(ptSchemeId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                    "入参节点错误，未传入患者队列实例id或值为空！"));
        }
        String userId = jsonTask.getString("patientId");
        if (null == userId || "".equals(userId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，患者id未传或值为空！"));
        }
        String taskId = jsonTask.getString("ptTaskId");
        if (null == taskId || "".equals(taskId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,
                    "入参节点错误，未传入患者任务id或值为空！"));
        }
        //Modified by Michael on 2022/06/28.
        final String executeTime= jsonTask.getString("executeTime");
        if (StringUtils.isEmpty(executeTime))   {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，未传入executeTime或值为空！"));
        }
        final String actualAge  = jsonTask.getString("actualAge");
        if (StringUtils.isEmpty(actualAge))   {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，未传入actualAge或值为空！"));
        }

        JSONObject jsonOpInfo = jsonData.getJSONObject("oprInfo");
        if (null == jsonOpInfo) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无oprInfo节点！"));
        }
        String opCode = jsonOpInfo.getString("opCode");
        if (null == opCode || "".equals(opCode)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无操作编码节点！"));
        }
        String currTime = jsonOpInfo.getString("opTime");// 入参中有操作时间，则使用入参中的时间
        if (StringUtils.isBlank(currTime)) {
            currTime = DateUtil.getTimeString(DateUtil.getSysDateA());
        }
        jsonOpInfo.put("updateTime", currTime);
        jsonOpInfo.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));

        String opType = jsonOpInfo.getString("opType");
        if (StringUtils.isBlank(opType)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作类型为空！"));
        }
        String opNote = jsonOpInfo.getString("opNote");
        if (StringUtils.isBlank(opNote)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作备注为空！"));
        }

        Map<String, Object> paramMap = new HashMap<String, Object>();
        // 创建人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        paramMap.put("sessionInfo", sessionMap);
        paramMap.put("oprInfo", jsonOpInfo);
        paramMap.put("taskInfo", jsonTask);

        Map<String, Object> retMap = new HashMap<String, Object>();
        retMap = patientInfoHisService.saveNewTempPatientTask(paramMap);

        return new ResultModel<Object>(retMap);
    }

    //TODO.
    /**
     * 更新临时随访。
     * @param arg
     * @param request
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/updateTempTask")
    public ResultModel<Object> updateTempTask(@RequestBody String arg, HttpServletRequest request) throws Exception {
        logger.info("++++updateTempTask----arg==" + arg);
        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            logger.error(ex.getMessage());
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }

        //检查3个必填参数。
        final String taskId = jsonData.getString("taskId");
        final String actualAge  = jsonData.getString("actualAge");
        final String executeTime= jsonData.getString("executeTime");
        if (StringUtils.isBlank(taskId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，taskId参数为空！"));
        }
        if (StringUtils.isBlank(actualAge)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，actualAge为空！"));
        }
        if (StringUtils.isBlank(executeTime)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，executeTime为空！"));
        }

        Map<String, Object> retMap = patientInfoHisService.updateTempTask(jsonData);
        if (retMap.get("success").toString().equals("true"))   {
            retMap.put("msg","成功修改了临时随访的计划随访日期。");
        } else {
            retMap.put("msg","修改临时随访的计划随访日期已失败！请咨询系统管理人员。");
        }
        return new ResultModel<Object>(retMap);
    }

    // 删除临时任务（当前日期无可编辑任务）
    @ResponseBody
    @RequestMapping("/delTempTask")
    public ResultModel<Object> delTempPatientTask(@RequestBody String arg,HttpServletRequest request) throws Exception {
        logger.warn("in delTempPatientTask----arg==" + arg);

        JSONObject jsonArg = null;
        try {
            jsonArg = JSON.parseObject(arg);
        } catch (Exception ex) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_FORMAT_ERROR, "入参错误，非json格式！"));
        }

        JSONObject jsonData = jsonArg.getJSONObject(Constants.INF_INPUTPARAM_COMMONFIELD);
        if (null == jsonData) {
            // 前台必须传data节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无data节点！"));
        }
        JSONObject jsonTask = jsonData.getJSONObject("taskInfo");
        if (null == jsonTask) {
            // 前台必须传task节点，否则报错返回
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无task节点！"));
        }
        String queueId = jsonTask.getString("followQueueId");
        if (null == queueId || "".equals(queueId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无队列id节点！"));
        }
        String ptSchemeId = jsonTask.getString("ptSchemeId");
        if (null == ptSchemeId || "".equals(ptSchemeId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,"入参节点错误，未传入患者队列实例id或值为空！"));
        }
        String userId = jsonTask.getString("patientId");
        if (null == userId || "".equals(userId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，患者id未传或值为空！"));
        }
        String taskId = jsonTask.getString("ptTaskId");
        if (null == taskId || "".equals(taskId)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR,"入参节点错误，未传入患者任务id或值为空！"));
        }
        JSONObject jsonOpInfo = jsonData.getJSONObject("oprInfo");
        if (null == jsonOpInfo) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无oprInfo节点！"));
        }
        String opCode = jsonOpInfo.getString("opCode");
        if (null == opCode || "".equals(opCode)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，无操作编码节点！"));
        }
        String currTime = jsonOpInfo.getString("opTime");// 入参中有操作时间，则使用入参中的时间
        if (StringUtils.isBlank(currTime)) {
            currTime = DateUtil.getTimeString(DateUtil.getSysDateA());
        }
        jsonOpInfo.put("updateTime", currTime);
        jsonOpInfo.put("updateAccept", SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_SYSTEMID));

        String opType = jsonOpInfo.getString("opType");
        if (StringUtils.isBlank(opType)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作类型为空！"));
        }
        String opNote = jsonOpInfo.getString("opNote");
        if (StringUtils.isBlank(opNote)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_INPUT_DATA_VERIFY_ERROR, "入参节点错误，操作备注为空！"));
        }
        Map<String, Object> paramMap =  Collections.synchronizedMap(new HashMap<String,Object>());
        // 操作人，从session中获取
        Map<String, Object> sessionMap = ToolUtils.getSessionInfo(request);
        paramMap.put("sessionInfo", sessionMap);
        paramMap.put("oprInfo", jsonOpInfo);
        paramMap.put("taskInfo", jsonTask);

        Map<String, Object> retMap = Collections.synchronizedMap(new HashMap<String,Object>());
        retMap = patientInfoHisService.delTempPatientTask(paramMap);

        return new ResultModel<Object>(retMap);
    }

    /**
     * 保存随访系统患者ID和HIS系统ID之间的映射。
     * @param followupPatId 随访系统患者ID
     * @param hisPatId HIS系统ID
     * @return "success", "fail".
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/save_followupid_hisid")
    public ResultModel<String> saveFollowupIdAndHisId(
            @RequestParam("followup_id") String followupPatId,
            @RequestParam("his_id") String hisPatId) throws Exception    {
        logger.info("saveFollowupIdAndHisId() followup_id:" + followupPatId + ", his_id:" + hisPatId);
        final String hisId = mapperService.selectByFuId(followupPatId);
        if (null != hisId && !hisId.isEmpty())  {
            //数据库中已保存该映射，不需要再次保存。
            return new ResultModel("success");
        } else {
            int saveResult = mapperService.save(followupPatId, hisPatId);
            if (1 == saveResult) {
                return new ResultModel("success");
            } else {
                return new ResultModel("fail");
            }
        }
    }

    /**
     * 根据随访ID查询HIS ID.
     * @param followupPatId
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("/gethisid")
    public ResultModel<String> getHisIdByFollowupId(@RequestParam("followup_pat_id") final String followupPatId) throws Exception    {
        final String hisId = mapperService.selectByFuId(followupPatId);
        if (null != hisId && !hisId.isEmpty()) {
            return new ResultModel<String>(hisId);
        } else {
            final String errorMsg = "随访患者ID:"+followupPatId+"没有对应的HIS系统ID!!";
            return new ResultModel(errorMsg);
        }
    }

}
